use cgmath::{vec2, Vector2};

#[derive(Debug, Clone, Copy)]
pub struct Rect {
    pub left: f32,
    pub right: f32,
    pub bottom: f32,
    pub top: f32,
}

impl Rect {
    pub fn root(width: f32, height: f32) -> Self {
        Self {
            left: 0.0,
            right: width,
            bottom: 0.0,
            top: height,
        }
    }

    pub fn new(left: f32, right: f32, bottom: f32, top: f32) -> Self {
        Self {
            left,
            right,
            bottom,
            top,
        }
    }

    pub fn from_position_size(
        position: Vector2<f32>,
        size: Vector2<f32>,
        pivot: Vector2<f32>,
    ) -> Self {
        let left = position.x - size.x * pivot.x;
        let right = position.x + size.x * (1.0 - pivot.x);
        let bottom = position.y - size.y * pivot.y;
        let top = position.y + size.y * (1.0 - pivot.y);

        Self {
            left,
            right,
            bottom,
            top,
        }
    }

    pub fn left_top(&self) -> Vector2<f32> {
        vec2(self.left, self.top)
    }

    pub fn left_bottom(&self) -> Vector2<f32> {
        vec2(self.left, self.bottom)
    }

    pub fn right_top(&self) -> Vector2<f32> {
        vec2(self.right, self.top)
    }

    pub fn right_bottom(&self) -> Vector2<f32> {
        vec2(self.right, self.bottom)
    }

    pub fn width(&self) -> f32 {
        (self.right - self.left).abs()
    }

    pub fn height(&self) -> f32 {
        (self.top - self.bottom).abs()
    }

    pub fn offset(&self, offset: Vector2<f32>) -> Rect {
        Rect {
            left: self.left + offset.x,
            right: self.right + offset.x,
            bottom: self.bottom + offset.y,
            top: self.top + offset.y,
        }
    }

    pub fn position(&self, pivot: Vector2<f32>) -> Vector2<f32> {
        vec2(
            self.left + self.width() * pivot.x,
            self.bottom + self.height() * pivot.y,
        )
    }

    pub fn contains(&self, p: Vector2<f32>) -> bool {
        return (self.left..self.right).contains(&p.x) && (self.bottom..self.top).contains(&p.y);
    }
}
